package logicaDePredicados;

import java.util.HashMap;

import exceptions.UnDecidibleValueException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

public class SkolemFunction<T, R> extends PredicateLogic {
	
	private HashMap <T,R> valueMap ;
	
	public SkolemFunction (String name){
		setName(name);
		valueMap = new HashMap<T, R>();
		
		
	}
	/**
	 * Add a value and a return value to the current Skolem function
	 * @param parameterValue
	 * @param returnValue
	 */
	public void addValue (T parameterValue, R returnValue){
		valueMap.put (parameterValue,returnValue);
		
	}
	/**
	 * Calculate the skolem function with the value given
	 * @param value
	 * @return the Skolem function value for the corresponding parameter value given.
	 * 
	 * @throws UnDecidibleValueException
	 */
	@SuppressWarnings("unchecked")
	public PredicateConstant<R> calculate (Object value) throws UnDecidibleValueException{
		R returnValue =	valueMap.get((T)value);
		if (returnValue==null){
			throw new UnDecidibleValueException ("undecidible value:"+value);
		}
		return new PredicateConstant<R>(returnValue,returnValue.toString().toUpperCase());
	}
	@Override
        public String toString(){
            return getName().concat("(x)");
        }
	public String getFullListing (){
		StringBuffer stringBuffer = new StringBuffer();
		stringBuffer.append(getName()+"\n");
		for (T iterable_element : valueMap.keySet()) {
			stringBuffer.append(iterable_element.toString()+"\t"+valueMap.get(iterable_element).toString()+"\n");
		}
		return stringBuffer.toString();
	}

         public Object [][] getDataMatrix (){

           Set<Entry <T,R>> entrySet = valueMap.entrySet();
           Object[][] matrix = new Object[entrySet.size()][entrySet.size()];
           int i=0;
           for (Entry<T, R> entry : entrySet) {
                matrix[i][0]= entry.getKey();
                matrix[i][1]=entry.getValue();
                i++;
           }
            return matrix;
        }
         /**
          * Returns a List containing the key values
          * @return
          */
        public List<T> getKeyList (){

            List <T> returnList = new LinkedList<T>();
            returnList.addAll(valueMap.keySet());
            return returnList;
        }

    public void removeKey(T element) {
        valueMap.remove(element);
    }

 
	
	
}
